/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.features.ruby_string.delayed;

import moved.org.objectweb.asm.MethodVisitor;

public class NamedVarInstruction extends AbstractMethodInstruction {
	private final String variableName;

	private VarInstruction varInstruction;

	private InvokeMethodInstruction appendInstruction;
	
	public NamedVarInstruction(String variableName) {
		this.variableName = variableName;
	}

	public void setVariableIndex(String desc, int index) {
		this.varInstruction = new VarInstruction(ILOAD, index);

		// TODO: Check for non primative types
		this.appendInstruction = new InvokeMethodInstruction(INVOKEVIRTUAL,
			"java/lang/StringBuffer", "append", "("+desc+")Ljava/lang/StringBuffer;");
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// MethodInstruction Methods
	///////////////////////////////////////////////////////////////////////////////////////////////

	public void accept(MethodVisitor methodVisitor) {
		if (varInstruction != null) {
			varInstruction.accept(methodVisitor);
			appendInstruction.accept(methodVisitor);
		}
		else {
			new LdcInstruction("{" + variableName + "}").accept(methodVisitor);
			new InvokeMethodInstruction(INVOKEVIRTUAL,
				"java/lang/StringBuffer", "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;")
				.accept(methodVisitor);
		}
	}

	@Override
	public void inform(MethodInstruction methodInstruction) {
		if (methodInstruction instanceof LocalVariableInstruction) {
			LocalVariableInstruction localVariableInstruction =
				(LocalVariableInstruction) methodInstruction;

			localVariableInstruction.update(this, variableName);
		}
	}
}
